package com.att.control;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.List;
import java.util.StringTokenizer;

import com.att.control.LinearInterpolator.Callback;
import com.att.control.LinearInterpolator.Point;

public class MonkeyEventHandler implements CommandHandler {
	
	private Socket s;
	private BufferedReader br;
	private BufferedWriter bw;
	
	public MonkeyEventHandler() {
		init();
	}
	
	@Override
	public void press(String keycode) {
		String cmd = "press " + keycode + "\n";
		execute(cmd);
	}

	@Override
	public void touch(String x, String y) {
		String cmd =  "tap " + x + " " + y + "\n";
		execute(cmd);
	}

	@Override
	public void drag(String startx, String starty, String endx, String endy,
			String steps, String during) {
		int _startx = Integer.valueOf(startx);
		int _starty = Integer.valueOf(starty);
		int _endx = Integer.valueOf(endx);
		int _endy = Integer.valueOf(endy);
		int _steps = Integer.valueOf(steps);
		long ms = Long.valueOf(during);
		
		 final long iterationTime = ms / _steps;

	        LinearInterpolator lerp = new LinearInterpolator(_steps);
	        LinearInterpolator.Point start = new LinearInterpolator.Point(_startx, _starty);
	        LinearInterpolator.Point end = new LinearInterpolator.Point(_endx, _endy);
	       
	        lerp.interpolate(start, end, new Callback() {
	            @Override
	            public void step(Point point) {
	                try {
	                	touchMove(point.getX(), point.getY());
	                    Thread.sleep(iterationTime);
	                } catch (InterruptedException e) {
	                	e.printStackTrace();
	                } 
	            }

	            @Override
	            public void start(Point point) {
	                try {
	                	touchDown(point.getX(), point.getY());
	                	touchMove(point.getX(), point.getY());
	                    Thread.sleep(iterationTime);
	                } catch (InterruptedException e) {
	                	e.printStackTrace();
	                } 
	            }

	            @Override
	            public void end(Point point) {
            		touchMove(point.getX(), point.getY());
                	touchUp(point.getX(), point.getY());
	            }
	        });

	}
	
	private void touchMove(int x, int y) {
		String cmd = "touch move " + x + " " + y + "\n";
		execute(cmd);
	}
	
	private void touchDown(int x, int y) {
		String cmd = "touch down " + x + " " + y + "\n";
		execute(cmd);
	}
	
	private void touchUp(int x, int y) {
		String cmd = "touch up " + x + " " + y + "\n";
		execute(cmd);
	}

	@Override
	public void longpress(String x, String y) {
		touchDown(Integer.valueOf(x), Integer.valueOf(y));
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		touchUp(Integer.valueOf(x), Integer.valueOf(y));
	}
	
	@Override
	public void type(String str) {
		StringTokenizer tok = new StringTokenizer(str, "\n", true);
		while (tok.hasMoreTokens()) {
            String line = tok.nextToken();
            if ("\n".equals(line)) {
              press("enter");
            } else {
            	String cmd = "type " + line + "\r\n";
            	execute(cmd);
            }
        }
	}

	@Override
	public void execute(List<String> cmd) {
		
	}

	@Override
	public void execute(String cmd) {
		try {
			bw.write(cmd);
			bw.flush();
			if (!s.isClosed()) {
				String result = br.readLine();
				System.out.println(result);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void init() {
		try {
			connectToDevice();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	private void connectToDevice() throws UnknownHostException, IOException, InterruptedException {
		Thread.sleep(1500);
		s = new Socket("127.0.0.1", AttMain.action_port);
		br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		
	}

	@Override
	public void quit() {
		String cmd = "quit\n";
		execute(cmd);
	}

	@Override
	public void physicsLongpress(String keycode) {
		String cmd1 =  "key down " + keycode + "\n";
		execute(cmd1);
		try {
			Thread.sleep(1200);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		String cmd2 =  "key up " + keycode + "\n";
		execute(cmd2);
	}

	

}
